package com.fpd.aspect;

import java.util.List;
import java.util.Map;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import com.fpd.annotation.LoginCheck;
import com.fpd.constant.SystemConstant;
import com.fpd.exceptions.NoLoginException;
import com.fpd.exceptions.NoPermissionException;
import com.fpd.tools.TokenUtil;
import com.fpd.tools.Tool;

/**
 * @desc 登录验证AOP切面实现
 * @author wujiangbo
 * @date 2019年11月18日 上午8:40:59
 */
@Component
@Aspect
public class LoginCheckAspect {

	@Value("${token.tokenTimeout}")
	private Integer tokenTimeout;

	@Value("${hc.loginCheckFlag}")
	private String loginCheckFlag;

	@Value("${hc.permissionFlag}")
	private String permissionFlag;

	@Autowired
	private RedisTemplate<Object, Object> redisTemplate;

	@Autowired
	private TokenUtil tokenUtil;

	/**
	 * @desc 登录验证AOP切面
	 * @author wujiangbo
	 * @date 2019年11月18日 上午8:44:03
	 * @param joinPoint  切入对象
	 * @param loginCheck 自定义注解
	 * @return Object
	 * @throws Throwable
	 */
	@Around("@annotation(loginCheck)")
	public Object loginCheck(ProceedingJoinPoint joinPoint, LoginCheck loginCheck) throws Throwable {
		if (Tool.isBlank(permissionFlag) || "1".equals(permissionFlag)) {
			// 获取当前用户请求头信息中的token信息
			String token = this.tokenUtil.getToken();
			if (Tool.isBlank(token)) {
				throw new NoLoginException("请求头信息中无token，请重新登录");
			}

			String userInfoRedisKey = SystemConstant.REDIS_USER_INFO_KEY + token;
			Map<Object, Object> map = this.redisTemplate.opsForHash().entries(userInfoRedisKey);
			if (map == null) {
				throw new NoLoginException("无用户信息，请重新登录");
			}
			// 权限验证字符串
			String permission = loginCheck.permission();
			if (!Tool.isBlank(permission)) {
				// 获取用户权限字符串集合
				Object permissionObj = map.get(SystemConstant.MAP_PERMISSION_LIST_KEY);
				if (permissionObj == null) {
					throw new NoPermissionException("暂无操作权限，请联系管理员开通");
				}
				List<String> permissionList = (List<String>) permissionObj;

				if (!permissionList.contains(permission)) {
					throw new NoPermissionException("暂无操作权限，请联系管理员开通(如已开通，请重新登录)");
				}
			}
		}
		return joinPoint.proceed();
	}
}
